package com.fy.module.sys.service.impl;

import com.fy.module.sys.common.vo.ResultVO;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fy.common.dto.LoginDto;
import com.fy.common.exception.JWTParseException;
import com.fy.common.exception.ServiceException;
import com.fy.common.vo.ApiRest;
import com.fy.module.sys.entity.SysCode;
import com.fy.module.sys.entity.UserMsg;
import com.fy.module.sys.mapper.PermissionMapper;
import com.fy.module.sys.mapper.RoleMapper;
import com.fy.module.sys.mapper.UserMapper;
import com.fy.module.sys.service.ICodeService;
import com.fy.module.sys.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import com.fy.utils.JwtUtils;
import com.fy.utils.RsaUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;


import javax.servlet.http.HttpServletResponse;
import java.security.PrivateKey;
import java.security.PublicKey;

import java.util.List;


import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author jiang
 * @since 2023-03-21
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserMsg> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public ResultVO findUserAllByUserId(int userId) {
        List<UserMsg> userMsgs = userMapper.selectAllByUserId(userId + "");
        if (userMsgs == null) {
            return new ResultVO(1,"用户不存在");
        }
        UserMsg user=userMsgs.get(0);
        return new ResultVO(0,"查询成功",user);
    }

    /**
     * 修改用户个人信息
     * @param
     * @return
     */

    @Override
    public ResultVO updateUser(String account,String phone, String email,String sex, String userId) {

        //修改用户信息
        int i = userMapper.updateUserMsg(account, phone, email, sex, userId);
        if (i<1){//受影响的行数为0，修改失败
            return new ResultVO(1,"基本信息修改失败，请重新尝试");
        }

        return new ResultVO(0,"基本信息修改成功");
    }

    /**
     * 修改用户密码
     * @param userId 用户id
     * @param oldPassword 旧密码
     * @param newPassword1 新密码1
     * @param newPassword2 确认密码
     * @return
     */
    @Override
    public ResultVO updatePassword(String userId,String oldPassword, String newPassword1, String newPassword2) {
        //查询出旧密码
        List<UserMsg> userMsgs = userMapper.selectAllByUserId(userId);

        //数据库密码
        String password=null;

        //得到数据库密码
        for (UserMsg userMsg : userMsgs) {
             password = userMsg.getPassword();

            }
        //对数据库的密码进行base64解析
        // byte[] decode = Base64.getDecoder().decode(password);
        // String pwd = new String(decode);

        //对数据库密码进行解析
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        //校验密码
        boolean matches = encoder.matches(oldPassword, password);
        if (!matches){
            return new ResultVO(1,"原密码输入错误，请重新输入");
        }

        //两次密码进行比对
        if (!newPassword1.equals(newPassword2)){
            return  new ResultVO(2,"两次密码输入不一致，请重新输入");
        }
        //以上对比成功后，对新密码进行bcrypt加密
        String encode = encoder.encode(newPassword1);
        //修改密码操作
        int i = userMapper.updateUserPassword(userId, encode );
        if (i<1){
            return new ResultVO(3,"非法参数");
        }

        return new ResultVO(0,"修改成功");
    }





    @Autowired
    private BCryptPasswordEncoder encoder;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private ICodeService codeService;

    @Override
    public ApiRest userLogin(LoginDto loginDto, HttpServletResponse response) {
        //非空判断
        if (loginDto == null) {
            throw new ServiceException("登录的用户信息不能为空");
        }
        if (loginDto.getUsername() == null || "".equals(loginDto.getUsername())) {
            throw new ServiceException("用户名不能为空");
        }
        if (loginDto.getPassword() == null || "".equals(loginDto.getPassword())) {
            throw new ServiceException("密码不能为空");
        }
        if (loginDto.getCode() == null || "".equals(loginDto.getCode())) {
            throw new ServiceException("验证码不能为空");
        }
        //验证码不正确
//        SysCode verifyCode = codeService.getVerifyCodeByCodeName(loginDto.getCode());
        List<SysCode> sysCodes = codeService.selectCodeList();
//        boolean flag = sysCodes.stream().anyMatch(s ->s.getCodeName().equalsIgnoreCase(loginDto.getCode()));
        SysCode sysCode = sysCodes.stream().filter(s -> s.getCodeName().equalsIgnoreCase(loginDto.getCode())).findAny().get();
        if (ObjectUtil.isEmpty(sysCode)) {
            //删除验证码
            return ApiRest.failure("验证码错误");
        }
        if (sysCode.getCodeName().equalsIgnoreCase(loginDto.getCode()) == false) {
            return ApiRest.failure("验证码错误");
        }

        //删除验证码
        codeService.deleteVerifyCode(sysCode.getCodeName());


        //将前端传过来的用户信息存到userMsg实体类中
        UserMsg userMsg = new UserMsg();
        userMsg.setAccount(loginDto.getUsername());
        userMsg.setPassword(loginDto.getPassword());

        //根据account查询用户对象
        QueryWrapper<UserMsg> queryWrap = new QueryWrapper<>();
        UserMsg user = this.userMapper.selectOne(queryWrap.eq("account", userMsg.getAccount()));
        System.out.println(user);

        //判断用户是否为空
        if (user == null) {
            return ApiRest.failure("用户名不存在", null);
        }

        //判断密码是否正确
        boolean flag = encoder.matches(userMsg.getPassword(), user.getPassword());
        if (!flag) {
            return ApiRest.failure("密码错误", null);
        }

        //判断用户是否选中记住密码
//        if(loginDto.getRememberMe()){//选中了记住密码
//            Cookie usernameCookie = new Cookie("username", loginDto.getUsername());
//            Cookie passwordCookie = new Cookie("password", loginDto.getPassword());
//            response.addCookie(usernameCookie);
//            response.addCookie(passwordCookie);
//        }

        //查询用户的角色名称
        List<String> roleNames = roleMapper.getRoleNames(user.getUserId());

        //查询用户的权限名称
        List<String> permNames = permissionMapper.getPermNames(user.getUserId());

        //调用糊涂根据包，将这两个集合合并成字符串
        String names = StrUtil.join(",", roleNames, permNames);

        //将合并之后名称set到user中
        user.setRoleNamesAndPermNames(names);

        //颁发令牌
        PrivateKey privateKey = null;
        try {
            //调用私钥进行加密
            privateKey = RsaUtils.getPrivateKey(ResourceUtils.getFile("classpath:pri").getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获取加密之后的令牌
        String token = JwtUtils.generateTokenExpireInMinutes(user, privateKey, 30);
        return ApiRest.success("登录成功", token);


    }

    @Override
    public ApiRest parseToken(String token) {
        //解析token

        //调用公钥解析token
        PublicKey publicKey = null;
        try {
            //调用RsaUtils工具类解析token
            publicKey = RsaUtils.getPublicKey(ResourceUtils.getFile("classpath:pub").getPath());

            //调用JWTUtils工具类。获取token中存放的用户信息
            UserMsg user = (UserMsg) JwtUtils.getInfoFromToken(token, publicKey, UserMsg.class);

            return ApiRest.success("合法的token", null);
        } catch (Exception e) {
            if (e instanceof JWTParseException) {
                return ApiRest.failure("不合法的token");
            } else {
                return ApiRest.failure(e.getMessage());
            }
        }
    }
}
